package com.itheima.pinda.controller;

import com.itheima.pinda.DTO.DriverJobDTO;
import com.itheima.pinda.DTO.TaskTransportDTO;
import com.itheima.pinda.DTO.transportline.TransportTripsDto;
import com.itheima.pinda.DTO.webManager.DriverJobQueryDTO;
import com.itheima.pinda.authority.api.AreaApi;
import com.itheima.pinda.authority.api.OrgApi;
import com.itheima.pinda.authority.api.UserApi;
import com.itheima.pinda.common.utils.PageResponse;
import com.itheima.pinda.feign.DriverJobFeign;
import com.itheima.pinda.feign.OrderFeign;
import com.itheima.pinda.feign.TransportOrderFeign;
import com.itheima.pinda.feign.TransportTaskFeign;
import com.itheima.pinda.feign.transportline.TransportTripsFeign;
import com.itheima.pinda.feign.truck.TruckFeign;
import com.itheima.pinda.feign.webManager.WebManagerFeign;
import com.itheima.pinda.future.PdCompletableFuture;
import com.itheima.pinda.util.BeanUtil;
import com.itheima.pinda.vo.base.angency.AgencyVo;
import com.itheima.pinda.vo.base.transforCenter.business.TransportTripsVo;
import com.itheima.pinda.vo.base.transforCenter.business.TruckVo;
import com.itheima.pinda.vo.base.userCenter.SysUserVo;
import com.itheima.pinda.vo.work.DriverJobVo;
import com.itheima.pinda.vo.work.TaskTransportVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;

/**
 * 司机作业单相关API
 *
 * @author itcast
 */
@RestController
@Slf4j
@Api(tags = "司机作业单相关API")
@RequestMapping("driver-job-manager")
public class DriverJobController {
    @Autowired
    private WebManagerFeign webManagerFeign;
    @Autowired
    private TransportTaskFeign transportTaskFeign;
    @Autowired
    private TransportTripsFeign transportTripsFeign;
    @Autowired
    private OrgApi orgApi;
    @Autowired
    private UserApi userApi;
    @Autowired
    private TruckFeign truckFeign;
    @Autowired
    private TransportOrderFeign transportOrderFeign;
    @Autowired
    private OrderFeign orderFeign;
    @Autowired
    private AreaApi areaApi;
    @Autowired
    private DriverJobFeign driverJobFeign;
    @SneakyThrows
    @ApiOperation(value = "获取司机作业单分页数据")
    @PostMapping("/page")
    public PageResponse<DriverJobVo> findByPage(@RequestBody DriverJobVo vo) {
        DriverJobDTO dto = new DriverJobDTO();
        if (vo != null) {
            dto.setPage(vo.getPage());
            dto.setPageSize(vo.getPageSize());
            if (vo.getDriver() != null) {
                dto.setDriverId(vo.getDriver().getUserId());
            }
            if (vo.getTaskTransport() != null) {
                dto.setTaskTransportId(vo.getTaskTransport().getId());
            }
            dto.setStatus(vo.getStatus());
            dto.setId(vo.getId());
        }

        PageResponse<DriverJobDTO> dtoPageResponse = driverJobFeign.findByPage(dto);

        //PageResponse<DriverJobDTO> dtoPageResponse = webManagerFeign.findDriverJobByPage(dto);
        List<DriverJobDTO> dtoList = dtoPageResponse.getItems();
        Set taskTransportIdSet = new HashSet<>();
        taskTransportIdSet.addAll(dtoList.stream().map(item -> item.getTaskTransportId()).collect(Collectors.toSet()));

        CompletableFuture taskTransportMapFuture = PdCompletableFuture.taskTransportMapFuture(transportTaskFeign, taskTransportIdSet);

        Set userIdSet = new HashSet<>();
        userIdSet.addAll(dtoList.stream().map(item -> item.getDriverId()).collect(Collectors.toSet()));

        Map<String, TaskTransportDTO> taskTransportMap = (Map<String, TaskTransportDTO>) taskTransportMapFuture.get();
        Set<Long> agencyIdSet = new HashSet<>();
        agencyIdSet.addAll(dtoList.stream().filter(item -> StringUtils.isNotEmpty(item.getStartAgencyId())).map(item -> Long.parseLong(item.getStartAgencyId())).collect(Collectors.toSet()));
        agencyIdSet.addAll(dtoList.stream().filter(item -> StringUtils.isNotEmpty(item.getEndAgencyId())).map(item -> Long.parseLong(item.getEndAgencyId())).collect(Collectors.toSet()));
        agencyIdSet.addAll(taskTransportMap.values().stream().filter(item -> StringUtils.isNotEmpty(item.getStartAgencyId())).map(item -> Long.parseLong(item.getStartAgencyId())).collect(Collectors.toSet()));
        agencyIdSet.addAll(taskTransportMap.values().stream().filter(item -> StringUtils.isNotEmpty(item.getEndAgencyId())).map(item -> Long.parseLong(item.getEndAgencyId())).collect(Collectors.toSet()));

        Set truckSet = new HashSet<>();
        truckSet.addAll(taskTransportMap.values().stream().map(item -> item.getTruckId()).collect(Collectors.toSet()));

        Set transportTripsIdSet = new HashSet<>();
        transportTripsIdSet.addAll(taskTransportMap.values().stream().map(item -> item.getTransportTripsId()).collect(Collectors.toSet()));


        CompletableFuture<Map> agencyMapFuture = PdCompletableFuture.agencyMapFuture(orgApi, agencyIdSet);
        CompletableFuture<Map> userMapFuture = PdCompletableFuture.userMapFuture(userApi, userIdSet, null, null, null);
        CompletableFuture<Map> truckMapFuture = PdCompletableFuture.truckMapFuture(truckFeign, truckSet, null);
        CompletableFuture<Map> transportTripsMapFuture = PdCompletableFuture.transportTripsMapFuture(transportTripsFeign, transportTripsIdSet);


        Map<String, AgencyVo> agencyMap = agencyMapFuture.get();
        Map<String, SysUserVo> userMap = userMapFuture.get();
        Map<String, TruckVo> truckMap = truckMapFuture.get();
        Map<String, TransportTripsDto> transportTripsMap = transportTripsMapFuture.get();
        List<DriverJobVo> voList = dtoList.stream().map(driverJobDTO -> {
            DriverJobVo driverJobVo = new DriverJobVo();
            BeanUtils.copyProperties(driverJobDTO, driverJobVo);

            if (agencyMap.containsKey(driverJobDTO.getStartAgencyId())) {
                driverJobVo.setStartAgency(BeanUtil.parseOrg2SimpleVo(agencyMap.get(driverJobDTO.getStartAgencyId())));
            }
            if (agencyMap.containsKey(driverJobDTO.getEndAgencyId())) {
                driverJobVo.setEndAgency(BeanUtil.parseOrg2SimpleVo(agencyMap.get(driverJobDTO.getEndAgencyId())));
            }

            if (userMap.containsKey(driverJobDTO.getDriverId())) {
                driverJobVo.setDriver(userMap.get(driverJobDTO.getDriverId()));
            }

            if (taskTransportMap.containsKey(driverJobDTO.getTaskTransportId())) {
                TaskTransportVo taskTransportVo = new TaskTransportVo();
                TaskTransportDTO taskTransportDTO = taskTransportMap.get(driverJobDTO.getTaskTransportId());
                BeanUtils.copyProperties(taskTransportDTO, taskTransportVo);
                if (transportTripsMap.containsKey(taskTransportDTO.getTransportTripsId())) {
                    TransportTripsVo transportTripsVo = new TransportTripsVo();
                    BeanUtils.copyProperties(transportTripsMap.get(taskTransportDTO.getTransportTripsId()), transportTripsVo);
                    taskTransportVo.setTransportTrips(transportTripsVo);
                }
                if (agencyMap.containsKey(taskTransportDTO.getStartAgencyId())) {
                    taskTransportVo.setStartAgency(BeanUtil.parseOrg2SimpleVo(agencyMap.get(taskTransportDTO.getStartAgencyId())));
                }
                if (agencyMap.containsKey(taskTransportDTO.getEndAgencyId())) {
                    taskTransportVo.setEndAgency(BeanUtil.parseOrg2SimpleVo(agencyMap.get(taskTransportDTO.getEndAgencyId())));
                }

                if (truckMap.containsKey(taskTransportDTO.getTruckId())) {
                    TruckVo truckVo = new TruckVo();
                    BeanUtils.copyProperties(truckMap.get(taskTransportDTO.getTruckId()), truckVo);
                    taskTransportVo.setTruck(truckVo);
                }
                driverJobVo.setTaskTransport(taskTransportVo);
            }

            return driverJobVo;
        }).collect(Collectors.toList());

        return PageResponse.<DriverJobVo>builder().items(voList).pagesize(vo.getPageSize()).page(vo.getPage()).counts(dtoPageResponse.getCounts()).pages(dtoPageResponse.getPages()).build();
    }
}
